<!--
 选择组件
 @Author: mosowe
 @Date:2023-03-06 09:21:37
-->

<template>
  <view
    :class="{
      'zo-group-choose': true,
      'zo-group-choose-col': props.col,
      'zo-group-choose-align-right': props.align === 'right'
    }"
    :style="{
      '--zo-group-choose-color': props.color,
      '--zo-group-choose-select-color': props.selectColor,
      '--zo-group-choose-icon-color': props.iconColor,
      '--zo-group-choose-icon-select-color': props.iconSelectColor,
      '--zo-group-choose-disabled-color': props.disabledColor,
      '--zo-group-choose-size': props.size
    }">
    <template
      v-for="(item, index) in showList"
      :key="index">
      <view
        v-if="!item.hide"
        :class="{
          'group-item': true,
          'group-item-diabled': item.disabled,
          'group-item-select':
            props.type === 'single'
              ? props.modelValue
              : Array.isArray(props.modelValue)
              ? props.modelValue?.includes(item.value)
              : props.modelValue === item.value
        }"
        @click.stop="chooseItem(item)">
        <view class="group-item-icon-wrap">
          <image
            :src="
              props.type === 'single'
                ? props.modelValue
                : (Array.isArray(props.modelValue) && props.modelValue?.includes(item.value)) ||
                  props.modelValue === item.value
                ? props.selectIcon
                : props.icon
            "
            mode="aspectFill"
            class="group-item-image"
            v-if="props?.icon && props?.icon.indexOf('/') > -1"></image>
          <text
            :class="{
              'group-item-icon': true,
              [props.icon]:
                props.type === 'single'
                  ? !props.modelValue
                  : Array.isArray(props.modelValue)
                  ? !props.modelValue?.includes(item.value)
                  : props.modelValue !== item.value,
              [props.selectIcon]:
                props.type === 'single'
                  ? props.modelValue
                  : Array.isArray(props.modelValue)
                  ? props.modelValue?.includes(item.value)
                  : props.modelValue === item.value
            }"
            v-else></text>
        </view>
        <text class="group-item-text">{{ item.label }}</text>
      </view>
    </template>
  </view>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
interface ListItem {
  label?: string; // 选项文案
  value: any; // 选项值
  hide?: boolean; // 是都隐藏
  disabled?: boolean; // 是否不可选
}

interface PropsType {
  modelValue: any; // v-model
  list?: ListItem[]; // 列表
  type?: 'radio' | 'checkbox' | 'single'; // 类型：单选、多选、单个选项
  singleText?: string[]; // 单个选择文案，[未选中，已选中]
  align?: 'right' | 'left'; // 对其方式
  color?: string; // 默认文本颜色
  selectColor?: string; // 选中文本颜色
  iconColor?: string; // 默认字体图标颜色
  iconSelectColor?: string; // 选中字体图标颜色
  disabledColor?: string; // 不可点击文案+字体图标颜色
  icon?: string; // 默认图标 字体或图片，默认及选中的必须一致类型
  selectIcon?: string; // 选中图标
  col?: boolean; // 垂直排列
  size?: string; // 尺寸大小，同步改变文字图标大小
}

const props = withDefaults(defineProps<PropsType>(), {
  type: 'radio',
  color: '#333333',
  selectColor: '#333333',
  iconColor: '#333333',
  iconSelectColor: '#333333',
  disabledColor: '#999999',
  icon: 'zoicon zo-circle',
  selectIcon: 'zoicon zo-dot-check',
  col: false,
  size: '28rpx'
});

// emits
interface EmitsType {
  (e: 'update:modelValue', data: any): void;
  (e: 'click', data: ListItem): void; // 选中时触发事件
}
const emits = defineEmits<EmitsType>();

const showList = computed(() => {
  if (props.type === 'single') {
    return [
      {
        label:
          props?.singleText && props?.singleText.length === 2
            ? props?.singleText[props.modelValue ? 1 : 0]
            : '',
        value: true
      }
    ];
  } else {
    return [...(props.list || [])];
  }
});

// 选择
const chooseItem = (item: ListItem) => {
  emits('click', item);
  if (item.disabled) {
    // 不可选
    return;
  }
  if (props.type === 'checkbox') {
    if (props.modelValue.includes(item.value)) {
      props.modelValue.splice(props.modelValue.indexOf(item.value), 1);
      emits('update:modelValue', [...props.modelValue]);
    } else {
      emits('update:modelValue', [...props.modelValue, item.value]);
    }
  } else if (props.type === 'single') {
    emits('update:modelValue', [0, false, null, undefined, ''].includes(props.modelValue));
  } else {
    emits('update:modelValue', item.value);
  }
};
</script>

<style lang="scss" scoped>
.zo-group-choose {
  display: flex;
  flex-wrap: wrap;
  &.zo-group-choose-col {
    flex-direction: column;
  }
  &.zo-group-choose-align-right {
    justify-content: flex-end;
    text-align: right;
  }
  .group-item {
    margin: 15rpx;
    font-size: var(--zo-group-choose-size);
    .group-item-icon-wrap {
      display: inline;
    }
    .group-item-image {
      width: var(--zo-group-choose-size);
      height: var(--zo-group-choose-size);
      vertical-align: middle;
    }
    .group-item-icon {
      font-size: var(--zo-group-choose-size);
      color: var(--zo-group-choose-icon-color);
    }
    .group-item-text {
      font-size: var(--zo-group-choose-size);
      margin-left: 10rpx;
      color: var(--zo-group-choose-color);
    }
    &.group-item-select {
      .group-item-icon {
        color: var(--zo-group-choose-icon-select-color);
      }
      .group-item-text {
        color: var(--zo-group-choose-select-color);
      }
    }
    &.group-item-diabled {
      .group-item-icon {
        color: var(--zo-group-choose-disabled-color);
      }
      .group-item-text {
        color: var(--zo-group-choose-disabled-color);
      }
      .group-item-image {
        -webkit-filter: grayscale(100%);
        -moz-filter: grayscale(100%);
        -ms-filter: grayscale(100%);
        -o-filter: grayscale(100%);
        filter: grayscale(100%);
        filter: gray;
      }
    }
  }
}
</style>
